"""
TabletService - 平板端数据处理服务
文件功能：处理平板端上传的脑波数据，进行实时分析和云端存储
处理原理：
1. 接收平板端脑波数据并缓存
2. 使用MNE进行数据预处理和滤波
3. 使用YASA进行睡眠阶段分析
4. 进行频域分析和功率谱计算
5. 将分析结果上传到云端存储
使用方法：通过process_data_and_analyze方法处理数据，通过get_latest_analysis_result获取分析结果
"""

import logging
import asyncio
import time
from typing import Dict, List, Any, Optional
from datetime import datetime, timedelta

from ..core.mne_processor import MNEProcessor
from ..core.yasa_analyzer import YASAAnalyzer
from ..core.realtime_analyzer import RealtimeAnalyzer
from ..service.cloud_api import get_cloud_api_service
from ..models.brain_wave_data import BrainWaveData, FrequencyData, TimeSeriesData
from ..config.settings import settings

logger = logging.getLogger(__name__)

class TabletService:
    """平板端数据处理服务"""
    
    def __init__(self):
        """初始化TabletService"""
        logger.info("初始化TabletService")
        
        # 初始化核心处理器
        self.mne_processor = MNEProcessor()
        self.yasa_analyzer = YASAAnalyzer()
        self.realtime_analyzer = RealtimeAnalyzer()
        
        # 初始化云端API服务
        self.cloud_api_service = get_cloud_api_service()
        
        # 数据缓存
        self.session_data_cache: Dict[str, List[Dict[str, Any]]] = {}
        self.deep_analysis_cache: Dict[str, Dict[str, Any]] = {}
        self.analysis_status: Dict[str, Dict[str, Any]] = {}
        
        # 原始数据上传缓存
        self.raw_data_upload_cache: Dict[str, Dict[str, Any]] = {}
        self.upload_tasks: Dict[str, asyncio.Task] = {}
        
        logger.info("TabletService初始化完成")
    
    async def process_data_and_analyze(self, session_id: str, data_point: Dict[str, Any]) -> None:
        """
        处理数据并进行异步分析
        
        Args:
            session_id: 会话ID
            data_point: 数据点
        """
        try:
            logger.debug(f"开始处理数据: session_id={session_id}")
            
            # 初始化会话缓存
            if session_id not in self.session_data_cache:
                self.session_data_cache[session_id] = []
            
            # 添加数据到缓存
            self.session_data_cache[session_id].append(data_point)
            
            # 更新分析状态
            self.analysis_status[session_id] = {
                'status': 'processing',
                'start_time': int(time.time() * 1000),
                'data_count': len(self.session_data_cache[session_id])
            }
            
            # 异步进行分析
            asyncio.create_task(self._perform_analysis_async(session_id))
            
            logger.debug(f"数据处理完成: session_id={session_id}")
            
        except Exception as e:
            logger.error(f"处理数据时发生错误: session_id={session_id}, error={str(e)}")
            self.analysis_status[session_id] = {
                'status': 'error',
                'error': str(e),
                'error_time': int(time.time() * 1000)
            }
    
    async def process_data_and_analyze_sync(self, session_id: str, room_id: str) -> Dict[str, Any]:
        """
        同步处理数据并返回分析结果
        
        Args:
            session_id: 会话ID
            room_id: 房间ID
            
        Returns:
            Dict[str, Any]: 分析结果
        """
        try:
            logger.debug(f"开始同步分析: session_id={session_id}, room_id={room_id}")
            
            # 获取会话数据
            session_data = self.session_data_cache.get(session_id, [])
            if not session_data:
                return {
                    'success': False,
                    'message': '暂无数据',
                    'session_id': session_id,
                    'timestamp': int(time.time() * 1000),
                    'received_data_points': 0,
                    'buffer_size': 0,
                    'yasa_available': True
                }
            
            # 进行频域分析
            frequency_result = self._perform_frequency_analysis(session_data)
            
            # 进行YASA分析（如果数据足够）
            yasa_result = None
            if len(session_data) >= 30:  # 至少30秒数据
                yasa_result = await self._perform_yasa_analysis(session_data)
            
            # 构建响应
            result = {
                'success': True,
                'message': '数据分析完成',
                'session_id': session_id,
                'timestamp': int(time.time() * 1000),
                'received_data_points': len(session_data),
                'buffer_size': len(session_data),
                'yasa_available': True
            }
            
            # 添加频域分析结果
            if frequency_result:
                result['frequency_bands'] = frequency_result.get('frequency_bands')
            
            # 添加YASA分析结果
            if yasa_result:
                result['sleep_stage'] = yasa_result.get('sleep_stage')
                result['confidence'] = yasa_result.get('confidence')
                result['epochs'] = yasa_result.get('epochs', [])
                result['total_epochs'] = len(yasa_result.get('epochs', []))
            
            logger.debug(f"同步分析完成: session_id={session_id}")
            return result
            
        except Exception as e:
            logger.error(f"同步分析时发生错误: session_id={session_id}, error={str(e)}")
            return {
                'success': False,
                'message': f'分析失败: {str(e)}',
                'session_id': session_id,
                'timestamp': int(time.time() * 1000),
                'received_data_points': len(self.session_data_cache.get(session_id, [])),
                'buffer_size': len(self.session_data_cache.get(session_id, [])),
                'yasa_available': True
            }
    
    async def get_latest_analysis_result(self, session_id: str) -> Optional[Dict[str, Any]]:
        """
        获取最新的分析结果
        
        Args:
            session_id: 会话ID
            
        Returns:
            Optional[Dict[str, Any]]: 分析结果
        """
        try:
            # 检查分析状态
            status_info = self.analysis_status.get(session_id)
            if not status_info:
                return None
            
            # 如果分析完成，返回缓存的结果
            if status_info.get('status') == 'completed':
                return self.deep_analysis_cache.get(session_id)
            
            # 如果正在处理，返回处理状态
            if status_info.get('status') == 'processing':
                current_time = int(time.time() * 1000)
                start_time = status_info.get('start_time', current_time)
                elapsed_seconds = (current_time - start_time) / 1000.0
                
                return {
                    'status': 'processing',
                    'start_time': start_time,
                    'elapsed_seconds': elapsed_seconds,
                    'data_count': status_info.get('data_count', 0)
                }
            
            # 如果有错误，返回错误信息
            if status_info.get('status') == 'error':
                return {
                    'status': 'error',
                    'error': status_info.get('error'),
                    'error_time': status_info.get('error_time')
                }
            
            return None
            
        except Exception as e:
            logger.error(f"获取分析结果时发生错误: session_id={session_id}, error={str(e)}")
            return None
    
    def _perform_frequency_analysis(self, session_data: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        """
        执行频域分析
        
        Args:
            session_data: 会话数据
            
        Returns:
            Optional[Dict[str, Any]]: 频域分析结果
        """
        try:
            if not session_data:
                return None
            
            logger.debug(f"开始频域分析，数据点数量: {len(session_data)}")
            
            # 提取原始数据
            raw_values = []
            for data_point in session_data:
                if 'raw_value' in data_point:
                    raw_values.extend(data_point['raw_value'])
            
            if not raw_values:
                return None
            
            # 使用MNE处理器进行频域分析
            brain_wave_data = BrainWaveData(
                session_id="temp",
                timestamp=int(time.time() * 1000),
                raw_data=raw_values,
                sampling_rate=256
            )
            
            # 进行频域分析
            frequency_data = self.mne_processor.analyze_frequency_bands(brain_wave_data)
            
            if frequency_data:
                # 计算频域功率比例
                total_power = sum([
                    frequency_data.delta_power,
                    frequency_data.theta_power,
                    frequency_data.alpha_power,
                    frequency_data.beta_power,
                    frequency_data.gamma_power
                ])
                
                if total_power > 0:
                    frequency_bands = {
                        'delta': frequency_data.delta_power / total_power,
                        'theta': frequency_data.theta_power / total_power,
                        'alpha': frequency_data.alpha_power / total_power,
                        'beta': frequency_data.beta_power / total_power,
                        'gamma': frequency_data.gamma_power / total_power
                    }
                    
                    return {'frequency_bands': frequency_bands}
            
            return None
            
        except Exception as e:
            logger.error(f"频域分析时发生错误: {str(e)}")
            return None
    
    async def _perform_yasa_analysis(self, session_data: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
        """
        执行YASA睡眠阶段分析
        
        Args:
            session_data: 会话数据
            
        Returns:
            Optional[Dict[str, Any]]: YASA分析结果
        """
        try:
            if len(session_data) < 30:  # 至少需要30秒数据
                return None
            
            logger.debug(f"开始YASA分析，数据点数量: {len(session_data)}")
            
            # 提取原始数据
            raw_values = []
            for data_point in session_data:
                if 'raw_value' in data_point:
                    raw_values.extend(data_point['raw_value'])
            
            if not raw_values:
                return None
            
            # 创建BrainWaveData对象
            brain_wave_data = BrainWaveData(
                session_id="temp",
                timestamp=int(time.time() * 1000),
                raw_data=raw_values,
                sampling_rate=256
            )
            
            # 使用YASA分析器进行睡眠阶段分析
            yasa_result = await self.yasa_analyzer.analyze_sleep_stages_realtime(brain_wave_data)
            
            if yasa_result:
                return {
                    'sleep_stage': yasa_result.get('current_stage', 'wake'),
                    'confidence': yasa_result.get('confidence', 0.0),
                    'epochs': yasa_result.get('epochs', [])
                }
            
            return None
            
        except Exception as e:
            logger.error(f"YASA分析时发生错误: {str(e)}")
            return None
    
    async def _perform_analysis_async(self, session_id: str) -> None:
        """
        异步执行分析
        
        Args:
            session_id: 会话ID
        """
        try:
            session_data = self.session_data_cache.get(session_id, [])
            if not session_data:
                return
            
            # 进行频域分析
            frequency_result = self._perform_frequency_analysis(session_data)
            
            # 进行YASA分析
            yasa_result = await self._perform_yasa_analysis(session_data)
            
            # 构建分析结果
            analysis_result = {
                'session_id': session_id,
                'timestamp': int(time.time() * 1000),
                'data_count': len(session_data)
            }
            
            if frequency_result:
                analysis_result.update(frequency_result)
            
            if yasa_result:
                analysis_result.update(yasa_result)
            
            # 缓存分析结果
            self.deep_analysis_cache[session_id] = analysis_result
            
            # 更新分析状态
            self.analysis_status[session_id] = {
                'status': 'completed',
                'completion_time': int(time.time() * 1000),
                'data_count': len(session_data)
            }
            
            logger.debug(f"异步分析完成: session_id={session_id}")
            
        except Exception as e:
            logger.error(f"异步分析时发生错误: session_id={session_id}, error={str(e)}")
            self.analysis_status[session_id] = {
                'status': 'error',
                'error': str(e),
                'error_time': int(time.time() * 1000)
            }
    
    def cleanup_old_data(self, max_age_hours: int = 24) -> None:
        """
        清理旧数据
        
        Args:
            max_age_hours: 最大保留时间（小时）
        """
        try:
            current_time = time.time()
            cutoff_time = current_time - (max_age_hours * 3600)
            
            # 清理会话数据缓存
            sessions_to_remove = []
            for session_id in self.session_data_cache.keys():
                # 检查分析状态中的时间戳
                status_info = self.analysis_status.get(session_id)
                if status_info:
                    last_time = status_info.get('start_time', 0) / 1000.0
                    if last_time < cutoff_time:
                        sessions_to_remove.append(session_id)
            
            # 移除旧数据
            for session_id in sessions_to_remove:
                self.session_data_cache.pop(session_id, None)
                self.deep_analysis_cache.pop(session_id, None)
                self.analysis_status.pop(session_id, None)
                self.raw_data_upload_cache.pop(session_id, None)
                
                # 停止上传任务
                if session_id in self.upload_tasks:
                    task = self.upload_tasks.pop(session_id)
                    if not task.done():
                        task.cancel()
            
            if sessions_to_remove:
                logger.info(f"清理了 {len(sessions_to_remove)} 个旧会话的数据")
                
        except Exception as e:
            logger.error(f"清理旧数据时发生错误: {str(e)}")
    
    def stop_upload_task(self, session_id: str) -> None:
        """
        停止上传任务
        
        Args:
            session_id: 会话ID
        """
        try:
            if session_id in self.upload_tasks:
                task = self.upload_tasks.pop(session_id)
                if not task.done():
                    task.cancel()
            
            # 清理上传缓存
            self.raw_data_upload_cache.pop(session_id, None)
            
        except Exception as e:
            logger.error(f"停止上传任务时发生错误: session_id={session_id}, error={str(e)}")